package com.carbeauty.entity;

import com.carbeauty.common.entity.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.*;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

import java.math.BigDecimal;
import java.time.LocalDate;

/**
 * 费用记录实体类
 * 
 * 费用管理功能:
 * - 门店各类费用记录
 * - 费用分类管理
 * - 费用统计分析
 * - 审批流程管理
 * 
 * 费用类型包括:
 * - 房租费用
 * - 水电费用
 * - 人工费用
 * - 材料采购费用
 * - 设备维护费用
 * - 营销推广费用
 * - 其他费用
 * 
 * @author CarBeauty Team
 */
@Entity
@Table(name = "cb_expense_record")
public class ExpenseRecord extends BaseEntity {
    
    /**
     * 费用名称
     */
    @NotBlank(message = "费用名称不能为空")
    @Size(max = 100, message = "费用名称长度不能超过100个字符")
    @Column(name = "expense_name", nullable = false, length = 100)
    private String expenseName;
    
    /**
     * 费用分类
     */
    @NotBlank(message = "费用分类不能为空")
    @Size(max = 50, message = "费用分类长度不能超过50个字符")
    @Column(name = "category", nullable = false, length = 50)
    private String category;
    
    /**
     * 费用金额
     */
    @NotNull(message = "费用金额不能为空")
    @DecimalMin(value = "0.01", message = "费用金额必须大于0")
    @Column(name = "amount", nullable = false, precision = 10, scale = 2)
    private BigDecimal amount;
    
    /**
     * 费用日期
     */
    @NotNull(message = "费用日期不能为空")
    @Column(name = "expense_date", nullable = false)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate expenseDate;
    
    /**
     * 供应商/收款方
     */
    @Size(max = 100, message = "供应商名称长度不能超过100个字符")
    @Column(name = "supplier", length = 100)
    private String supplier;
    
    /**
     * 联系方式
     */
    @Size(max = 100, message = "联系方式长度不能超过100个字符")
    @Column(name = "contact", length = 100)
    private String contact;
    
    /**
     * 发票号码
     */
    @Size(max = 50, message = "发票号码长度不能超过50个字符")
    @Column(name = "invoice_no", length = 50)
    private String invoiceNo;
    
    /**
     * 是否已开发票
     */
    @Column(name = "has_invoice")
    private Boolean hasInvoice = false;
    
    /**
     * 支付方式
     */
    @Size(max = 20, message = "支付方式长度不能超过20个字符")
    @Column(name = "payment_method", length = 20)
    private String paymentMethod;
    
    /**
     * 是否已支付
     */
    @Column(name = "is_paid")
    private Boolean isPaid = false;
    
    /**
     * 支付日期
     */
    @Column(name = "payment_date")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate paymentDate;
    
    /**
     * 操作员ID - 不使用外键约束
     */
    @Column(name = "operator_id")
    private Long operatorId;
    
    /**
     * 操作员姓名 - 冗余字段
     */
    @Size(max = 50, message = "操作员姓名长度不能超过50个字符")
    @Column(name = "operator_name", length = 50)
    private String operatorName;
    
    /**
     * 审批人ID - 不使用外键约束
     */
    @Column(name = "approver_id")
    private Long approverId;
    
    /**
     * 审批人姓名 - 冗余字段
     */
    @Size(max = 50, message = "审批人姓名长度不能超过50个字符")
    @Column(name = "approver_name", length = 50)
    private String approverName;
    
    /**
     * 审批状态 (PENDING-待审批, APPROVED-已审批, REJECTED-已拒绝)
     */
    @Size(max = 20, message = "审批状态长度不能超过20个字符")
    @Column(name = "approval_status", length = 20)
    private String approvalStatus = "PENDING";
    
    /**
     * 审批时间
     */
    @Column(name = "approval_date")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate approvalDate;
    
    /**
     * 审批意见
     */
    @Size(max = 200, message = "审批意见长度不能超过200个字符")
    @Column(name = "approval_comment", length = 200)
    private String approvalComment;
    
    /**
     * 费用描述
     */
    @Size(max = 500, message = "费用描述长度不能超过500个字符")
    @Column(name = "description", length = 500)
    private String description;
    
    /**
     * 附件URL(多个附件用逗号分隔)
     */
    @Size(max = 500, message = "附件URL长度不能超过500个字符")
    @Column(name = "attachments", length = 500)
    private String attachments;
    
    // ==================== 构造方法 ====================
    
    public ExpenseRecord() {
        super();
        this.expenseDate = LocalDate.now();
    }
    
    public ExpenseRecord(String expenseName, String category, BigDecimal amount) {
        this();
        this.expenseName = expenseName;
        this.category = category;
        this.amount = amount;
    }
    
    // ==================== Getter/Setter ====================
    
    public String getExpenseName() {
        return expenseName;
    }
    
    public void setExpenseName(String expenseName) {
        this.expenseName = expenseName;
    }
    
    public String getCategory() {
        return category;
    }
    
    public void setCategory(String category) {
        this.category = category;
    }
    
    public BigDecimal getAmount() {
        return amount;
    }
    
    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }
    
    public LocalDate getExpenseDate() {
        return expenseDate;
    }
    
    public void setExpenseDate(LocalDate expenseDate) {
        this.expenseDate = expenseDate;
    }
    
    public String getSupplier() {
        return supplier;
    }
    
    public void setSupplier(String supplier) {
        this.supplier = supplier;
    }
    
    public String getContact() {
        return contact;
    }
    
    public void setContact(String contact) {
        this.contact = contact;
    }
    
    public String getInvoiceNo() {
        return invoiceNo;
    }
    
    public void setInvoiceNo(String invoiceNo) {
        this.invoiceNo = invoiceNo;
    }
    
    public Boolean getHasInvoice() {
        return hasInvoice;
    }
    
    public void setHasInvoice(Boolean hasInvoice) {
        this.hasInvoice = hasInvoice;
    }
    
    public String getPaymentMethod() {
        return paymentMethod;
    }
    
    public void setPaymentMethod(String paymentMethod) {
        this.paymentMethod = paymentMethod;
    }
    
    public Boolean getIsPaid() {
        return isPaid;
    }
    
    public void setIsPaid(Boolean isPaid) {
        this.isPaid = isPaid;
    }
    
    public LocalDate getPaymentDate() {
        return paymentDate;
    }
    
    public void setPaymentDate(LocalDate paymentDate) {
        this.paymentDate = paymentDate;
    }
    
    public Long getOperatorId() {
        return operatorId;
    }
    
    public void setOperatorId(Long operatorId) {
        this.operatorId = operatorId;
    }
    
    public String getOperatorName() {
        return operatorName;
    }
    
    public void setOperatorName(String operatorName) {
        this.operatorName = operatorName;
    }
    
    public Long getApproverId() {
        return approverId;
    }
    
    public void setApproverId(Long approverId) {
        this.approverId = approverId;
    }
    
    public String getApproverName() {
        return approverName;
    }
    
    public void setApproverName(String approverName) {
        this.approverName = approverName;
    }
    
    public String getApprovalStatus() {
        return approvalStatus;
    }
    
    public void setApprovalStatus(String approvalStatus) {
        this.approvalStatus = approvalStatus;
    }
    
    public LocalDate getApprovalDate() {
        return approvalDate;
    }
    
    public void setApprovalDate(LocalDate approvalDate) {
        this.approvalDate = approvalDate;
    }
    
    public String getApprovalComment() {
        return approvalComment;
    }
    
    public void setApprovalComment(String approvalComment) {
        this.approvalComment = approvalComment;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public String getAttachments() {
        return attachments;
    }
    
    public void setAttachments(String attachments) {
        this.attachments = attachments;
    }
    
    // ==================== 业务方法 ====================
    
    /**
     * 审批通过
     */
    public void approve(Long approverId, String approverName, String comment) {
        this.approverId = approverId;
        this.approverName = approverName;
        this.approvalStatus = "APPROVED";
        this.approvalDate = LocalDate.now();
        this.approvalComment = comment;
    }
    
    /**
     * 审批拒绝
     */
    public void reject(Long approverId, String approverName, String comment) {
        this.approverId = approverId;
        this.approverName = approverName;
        this.approvalStatus = "REJECTED";
        this.approvalDate = LocalDate.now();
        this.approvalComment = comment;
    }
    
    /**
     * 标记为已支付
     */
    public void markAsPaid(String paymentMethod) {
        this.isPaid = true;
        this.paymentMethod = paymentMethod;
        this.paymentDate = LocalDate.now();
    }
    
    /**
     * 检查是否待审批
     */
    public boolean isPending() {
        return "PENDING".equals(approvalStatus);
    }
    
    /**
     * 检查是否已审批
     */
    public boolean isApproved() {
        return "APPROVED".equals(approvalStatus);
    }
    
    /**
     * 检查是否已拒绝
     */
    public boolean isRejected() {
        return "REJECTED".equals(approvalStatus);
    }
    
    /**
     * 获取附件列表
     */
    public String[] getAttachmentList() {
        if (attachments != null && !attachments.trim().isEmpty()) {
            return attachments.split(",");
        }
        return new String[0];
    }
    
    /**
     * 设置附件列表
     */
    public void setAttachmentList(String[] attachmentList) {
        if (attachmentList != null && attachmentList.length > 0) {
            this.attachments = String.join(",", attachmentList);
        } else {
            this.attachments = null;
        }
    }
    
    // ==================== 费用分类常量 ====================
    
    /**
     * 房租费用
     */
    public static final String CATEGORY_RENT = "房租费用";
    
    /**
     * 水电费用
     */
    public static final String CATEGORY_UTILITIES = "水电费用";
    
    /**
     * 人工费用
     */
    public static final String CATEGORY_LABOR = "人工费用";
    
    /**
     * 材料采购费用
     */
    public static final String CATEGORY_MATERIAL = "材料采购费用";
    
    /**
     * 设备维护费用
     */
    public static final String CATEGORY_EQUIPMENT = "设备维护费用";
    
    /**
     * 营销推广费用
     */
    public static final String CATEGORY_MARKETING = "营销推广费用";
    
    /**
     * 其他费用
     */
    public static final String CATEGORY_OTHER = "其他费用";
}
